/*
* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//import { canvas } from "../libs/weapp-adapter";
const { TextEditor } = require("./XTextInput.js");
const { X2DBeta, X3DFast } = require("./graphics/X2DInterface.js");
const { XFbo } = require("./graphics/XFbo.js");
const { XShader } = require("./graphics/X2DInterface.js");
const { Scr } = require("./XDefine.js");
const { XTools } = require("./XTools.js");
const { XMat4 } = require("./graphics/XMat4.js");
const { XPlatform } = require("./XPlatform.js");

function touch_start(e) { e.preventDefault(); GLFrame.pinstance_.callback_proctouch(1, e.touches[0].clientX, e.touches[0].clientY); }
function touch_move(e) { e.preventDefault(); GLFrame.pinstance_.callback_proctouch(2, e.touches[0].clientX, e.touches[0].clientY); }
function touch_end(e) { e.preventDefault(); GLFrame.pinstance_.callback_proctouch(3, e.changedTouches[0].clientX, e.changedTouches[0].clientY); }

function mouse_down(e) {
    e.preventDefault();
    switch (e.button) {
        case 0:
            GLFrame.pinstance_.callback_proctouch(1, e.clientX, e.clientY);
            break;
        case 2:
            GLFrame.pinstance_.callback_proctouch(4, e.clientX, e.clientY);
            break;
    }

}
function mouse_move(e) {
    e.preventDefault();
    GLFrame.pinstance_.callback_proctouch(2, e.clientX, e.clientY);
}
function mouse_up(e) {
    e.preventDefault();
    switch (e.button) {
        case 0:
            GLFrame.pinstance_.callback_proctouch(3, e.clientX, e.clientY);
            break;
        case 2:
            GLFrame.pinstance_.callback_proctouch(6, e.clientX, e.clientY);
            break;
    }
}

function mouse_out(e) {
    e.preventDefault();
    if (XTools.MOUSE_POS.down) {
        GLFrame.pinstance_.callback_proctouch(3, e.clientX, e.clientY);
    }
    if (XTools.MOUSE_POS.rdown) {
        GLFrame.pinstance_.callback_proctouch(6, e.clientX, e.clientY);
    }
}

function mouse_wheel(e) {
    e.preventDefault();
    if (e.wheelDeltaY > 0) {//往下100   往上-100
        GLFrame.pinstance_.callback_proctouch(10, e.clientX, e.clientY);
    }
    else {
        GLFrame.pinstance_.callback_proctouch(11, e.clientX, e.clientY);
    }
}

// function key_down(e) { GLFrame.pinstance_.callback_key(1, e.keyCode ? e.keyCode : e.which) }
function key_up(e) {
    if (!e.ctrlKey) {
        XTools.KEY_CTRL = false;
    }
    if (!e.shiftKey) {
        XTools.KEY_SHIFT = false;
    }
    if (!e.altKey) {
        XTools.KEY_ALT = false;
    }
    GLFrame.pinstance_.callback_key(0, e.key);
    e.preventDefault();
}
// function key_press(e) { GLFrame.pinstance_.callback_key(0, e.keyCode ? e.keyCode : e.which) }
function key_down(e) {
    // if(e.keyCode>47 && e.keyCode<91)
    // {
    //     GLFrame.pinstance_.callback_key(1, e.key.charCodeAt(0))
    // }
    let ret = "";
    if (e.ctrlKey) {
        ret += "ctrl+";
        XTools.KEY_CTRL = true;
    }
    if (e.shiftKey) {
        ret += "shift+";
        XTools.KEY_SHIFT = true;
    }
    if (e.altKey) {
        ret += "alt+";
        XTools.KEY_ALT = true;
    }
    ret += e.key;
    GLFrame.pinstance_.callback_key(1, ret);
    if (!e.key.startsWith("F")) {
        e.preventDefault();
    }
}

function main_loop() {
    GLFrame.pinstance_.callback_draw();
    window.requestAnimationFrame(main_loop)
}

class GLFrame {
    static gi() {
        if (GLFrame.pinstance_ == null) {
            GLFrame.pinstance_ = new GLFrame();
        }
        return GLFrame.pinstance_;
    }
    constructor() {
    }

    Go(cvs, _draw = null, _touch = null, _key = null, _logic = null) {
        this.cvs_ = cvs;
        // let canvas=wx.createCanvas()
        // gl = cvs.getContext('webgl', { premultipliedAlpha: false });
        cvs.addEventListener('webglcontextcreationerror', (e) => {
            alert(e.statusMessage || 'Unknown error');
        }, false);
        console.log(window.USE_WEBGL_VERSION == 2 ? 'webgl2' : 'webgl');
        window.gl = cvs.getContext(window.USE_WEBGL_VERSION == 2 ? 'webgl2' : 'webgl', { antialias: true });
        console.log(window.gl);
        this.lc_ = window.gl.getExtension('WEBGL_lose_context');
        XShader.gi();
        X3DFast.init();

        this.pCallbackDraw = _draw
        this.pCallbackTouch = _touch
        this.pCallbackKey = _key
        this.pCallbackLogic = _logic
        this.callbackDropfile_ = null;

        cvs.addEventListener("touchstart", touch_start);
        cvs.addEventListener("touchmove", touch_move);
        cvs.addEventListener("touchend", touch_end);

        cvs.addEventListener("mousedown", mouse_down);
        cvs.addEventListener("mousemove", mouse_move);
        cvs.addEventListener("mouseup", mouse_up);
        cvs.addEventListener("mouseout", mouse_out);
        cvs.addEventListener("mousewheel", mouse_wheel);

        cvs.addEventListener("webglcontextlost", (e) => {
            // console.log("sdf");
            // gl = cvs.getContext('webgl2', { antialias: true });
            window.cancelAnimationFrame(this.requestId);
            e.preventDefault();
            this.lc_.restoreContext();
        }, false);
        cvs.addEventListener("webglcontextrestored", (e) => {
            console.log("asd");
            gl = cvs.getContext('webgl2', { antialias: true });
        }, false);

        cvs.addEventListener("drop", (e) => {
            e.preventDefault();
            GLFrame.gi().callback_dropfile(e.dataTransfer.files, e.offsetX, e.offsetY);
        });
        cvs.addEventListener("dragover", (e) => {
            e.preventDefault();
        });
        cvs.addEventListener("dragenter", (e) => {
            e.preventDefault();
        });

        cvs.focus();
        cvs.addEventListener('keydown', key_down);
        // cvs.onkeydown=key_down;
        cvs.addEventListener('keyup', key_up);
        // window.addEventListener('keypress', key_press);

        document.addEventListener('contextmenu', function (e) {
            e.preventDefault();
        })

        this.requestId = window.requestAnimationFrame(main_loop);

        X2DBeta.Init();
    }
    callback_key(type, code) {
        if (this.pCallbackKey != null) {
            return this.pCallbackKey(type, code)
        }
        return false;
    }
    callback_draw() {
        // let gamepads = navigator.getGamepads();
        // console.log(gamepads);

        X2DBeta.WORLD_MAT.Unit();
        X2DBeta.WORLD_MAT.X2DMat(0, 0, Scr.logicw, Scr.logich);
        X2DBeta.TEXT_MAT.Unit();
        X2DBeta.TEXT_MAT.X2DMat(0, 0, Scr.realw, Scr.realh);

        window.gl.viewport(0, 0, Scr.realw, Scr.realh);
        // window.gl.viewport(50, 50, Scr.realw-100, Scr.realh-100-1800);
        window.gl.clearColor(0.0, 0.0, 0.0, 1.0);
        window.gl.clear(window.gl.COLOR_BUFFER_BIT | window.gl.DEPTH_BUFFER_BIT | window.gl.STENCIL_BUFFER_BIT);
        if (this.pCallbackDraw != null) {
            this.pCallbackDraw();
        }
        // this.fbo_.StartFBO(true);
        // window.gl.viewport(0, 0, Scr.logicw, Scr.logich);
        // X2DBeta.ResetMat(Scr.logicw, Scr.logich);
        // if (this.pCallbackDraw != null) {
        //     this.pCallbackDraw();
        // }
        // this.fbo_.StopFBO(true);

        // window.gl.viewport(0, 0, Scr.realw, Scr.realh);
        // X2DBeta.ResetMat(Scr.realw, Scr.realh);
        // window.gl.clearColor(0.0, 0.0, 0.0, 1.0);
        // window.gl.clear(window.gl.COLOR_BUFFER_BIT | window.gl.DEPTH_BUFFER_BIT);
        // //X2DBeta.drawCut(this.fbo_.cid_, 0, Scr.realh / 2, Scr.rate, -Scr.rate, 0, 0, Scr.realh / 2, 0xffffffff);
        // X2DBeta.drawCut(this.fbo_.cid_, 0, Scr.realh, Scr.rate, -Scr.rate, 0, 0, 0, 0xffffffff);
        // X2DBeta.Flush();
    }
    callback_proctouch(msg, x, y) {
        if (msg == 1) {
            this.cvs_.focus();
            TextEditor.NormalTextInput.Hide();
            TextEditor.CodeTextInput.Hide();
        }
        x = parseInt(x * Scr.fMouseModifyX);
        y = parseInt(y * Scr.fMouseModifyY);
        XTools.MOUSE_POS.x = x;
        XTools.MOUSE_POS.y = y;
        if (msg == 1) {
            XTools.MOUSE_POS.down = true;
        }
        else if (msg == 3) {
            XTools.MOUSE_POS.down = false;
        }
        if (msg == 4) {
            XTools.MOUSE_POS.rdown = true;
        }
        else if (msg == 6) {
            XTools.MOUSE_POS.rdown = false;
        }
        if (this.pCallbackTouch != null) {
            this.pCallbackTouch(msg, x, y);
        }
    }
    callback_dropfile(files, x, y) {
        if (this.callbackDropfile_) {
            this.callbackDropfile_(files, x, y);
        }
    }
    resize() {
        // window.gl.viewport(0, 0, Scr.realw, Scr.realh);
        // this.fbo_.reInit(Scr.logicw, Scr.logich);
        // X2DBeta.ResetTextMat(Scr.realw, Scr.realh);
    }
    static TYPE_DROPFILE = 1;
    RegistCallback(type, cb) {
        switch (type) {
            case GLFrame.TYPE_DROPFILE:
                this.callbackDropfile_ = cb;
                break;
        }
    }
    SnapShot() {
        const imageData = this.cvs_.toDataURL('image/png');

        // 创建一个下载链接
        const link = document.createElement('a');
        link.href = imageData;
        link.download = 'snapshot.png';

        link.addEventListener('click', () => {
            // 在保存完成后清除链接
            setTimeout(() => {
                URL.revokeObjectURL(link.href);
                link.remove();
            }, 100);
        });

        // 模拟点击下载链接
        link.click();
    }
}

GLFrame.pinstance_ = null;

module.exports = {
    GLFrame,
}
